# import jusmargui
from PySide2.QtWidgets import (
    QApplication,
    QWidget,
    QTableWidgetItem,
    QTableWidget,
    QHeaderView,
    QAbstractItemView,
    QVBoxLayout,
    QTabWidget,
    QGroupBox,
    QLabel,
    QLineEdit,
    QHBoxLayout,
    QGridLayout,
    QComboBox,
    QPushButton,
    QListWidget,
    QDialog,
    QButtonGroup,
    QRadioButton,
    QCheckBox,
    QListWidgetItem,
    QMessageBox,
    QGraphicsColorizeEffect,
    QFileDialog,
    QSpacerItem,
    QSizePolicy,
)

from PySide2.QtCore import Qt, Signal
from PySide2.QtGui import QPixmap, QDoubleValidator, QIntValidator, QImage, QColor
import sys
import csv
import os
import json
import subprocess
import copy
from gui.controls import envs
from .. import message_box as MBox
from .. import config as Config
from ..utils import Utils
from ..dlg_model_params import DlgModeResetCls
from ..params_table import ParamsTable, OnlyOneRowTable
from ..custom_widget import LineEditFloat, LineEditStr, SelectBox, LineEditInt


class DlgSkeletalStructure(DlgModeResetCls):
    skeletalStructure_save_signal = Signal(object)
    materialLibraryLocking_update_signal = Signal(object)
    stringedBarLibraryLocking_update_signal = Signal(object)

    def __init__(self, parent=None, params={}):
        super().__init__(parent)
        title = f"杆系-{params.get('title')or''}"
        self.setWindowTitle(title)
        self.resize(700, -1)

        self.materialData = Utils.read_json(Config.cachePath + "materialLibrary.json")
        self.materialOptions = []
        if self.materialData:
            for key, _ in self.materialData.items():
                self.materialOptions.append({"title": key, "value": key})

        self.stringedBarData = Utils.read_json(
            Config.cachePath + "stringedBarLibrary.json"
        )
        self.stringedBarOptions = []
        if self.stringedBarData:
            for key, _ in self.stringedBarData.items():
                self.stringedBarOptions.append({"title": key, "value": key})

        self.widgetDict = {}

        layout = QVBoxLayout()
        topSurfaceGroupBox = QGroupBox("上端面")
        topSurfaceLayout = QVBoxLayout()
        self.widgetDict["topSurface"] = OnlyOneRowTable(
            rows=0, columns=7, isNoAddAndDel=True
        )
        self.widgetDict["topSurface"].setHorizontalHeaderLabels(
            ["节点号", "x坐标", "y坐标", "z坐标", "半径", "材料", "截面"]
        )
        self.widgetDict["topSurface"].rowSetInt([0])
        self.widgetDict["topSurface"].rowSetFloat([1, 2, 3, 4])
        self.widgetDict["topSurface"].rowSetSelect(
            [5, 6],
            {
                "5": self.materialOptions,
                "6": self.stringedBarOptions,
            },
        )
        self.widgetDict["topSurface"].noEditHint = "该数据已入库，不可修改节点号！"
        self.widgetDict["topSurface"].uniqueFlagColumn = 0
        self.widgetDict["topSurface"].addRow()
        self.setTableFixeHeight(self.widgetDict["topSurface"])
        topSurfaceLayout.addWidget(self.widgetDict["topSurface"])
        topSurfaceGroupBox.setLayout(topSurfaceLayout)

        bottomSurfaceGroupBox = QGroupBox("下端面")
        bottomSurfaceLayout = QVBoxLayout()
        self.widgetDict["bottomSurface"] = OnlyOneRowTable(
            rows=0, columns=7, isNoAddAndDel=True
        )
        self.widgetDict["bottomSurface"].setHorizontalHeaderLabels(
            ["节点号", "x坐标", "y坐标", "z坐标", "半径", "材料", "截面"]
        )
        self.widgetDict["bottomSurface"].rowSetInt([0])
        self.widgetDict["bottomSurface"].rowSetFloat([1, 2, 3, 4])
        self.widgetDict["bottomSurface"].rowSetSelect(
            [5, 6],
            {
                "5": self.materialOptions,
                "6": self.stringedBarOptions,
            },
        )
        self.widgetDict["bottomSurface"].noEditHint = "该数据已入库，不可修改节点号！"
        self.widgetDict["bottomSurface"].uniqueFlagColumn = 0
        self.widgetDict["bottomSurface"].addRow()
        self.setTableFixeHeight(self.widgetDict["bottomSurface"])
        bottomSurfaceLayout.addWidget(self.widgetDict["bottomSurface"])
        bottomSurfaceGroupBox.setLayout(bottomSurfaceLayout)

        ySkeletalGroupBox = QGroupBox("Y形杆系")
        ySkeletalLayout = QHBoxLayout()
        leftGridLayout = QGridLayout()
        rightGridLayout = QGridLayout()
        ySkeletalList = [
            {"name": "num_r", "type": "int", "title": "杆系环向个数"},
            {"name": "len_r", "type": "float", "title": "环向单元尺寸"},
            {"name": "start_angle", "type": "float", "title": "起始角度"},
            {"name": "num_rod", "type": "int", "title": "单杆单元数"},
            {
                "name": "material",
                "type": "select",
                "title": "材料",
                "options": self.materialOptions,
            },
            {
                "name": "rib",
                "type": "select",
                "title": "截面",
                "options": self.stringedBarOptions,
            },
            {"name": "element_start", "type": "int", "title": "单元起始编号"},
            {"name": "rib_start", "type": "int", "title": "属性起始编号"},
        ]
        self.createParameterUI(ySkeletalList[:4], leftGridLayout)
        self.createParameterUI(ySkeletalList[4:], rightGridLayout)
        ySkeletalLayout.addLayout(leftGridLayout)
        ySkeletalLayout.addLayout(rightGridLayout)
        ySkeletalGroupBox.setLayout(ySkeletalLayout)

        layout.addWidget(topSurfaceGroupBox)
        layout.addWidget(bottomSurfaceGroupBox)
        layout.addWidget(ySkeletalGroupBox)

        btnLayout = QHBoxLayout()
        cancelBtn = QPushButton("取消")
        okBtn = QPushButton("确定")

        btnLayout.setAlignment(Qt.AlignCenter)

        btnLayout.addWidget(okBtn)
        btnLayout.addWidget(cancelBtn)
        layout.addLayout(btnLayout)

        okBtn.clicked.connect(self.on_okBtn_clicked)
        cancelBtn.clicked.connect(self.close)

        self.setLayout(layout)

        data = {}
        if Config.isLocation:
            self.cacheFile = Config.cachePath + "skeletalStructure.json"
            data = Utils.read_json(self.cacheFile)
        else:
            data = params.get("data") or {}
        self.updateUI(data)
        Utils.handleTableNoEdit(
            data=data.get("topSurface"), table=self.widgetDict["topSurface"]
        )
        Utils.handleTableNoEdit(
            data=data.get("bottomSurface"), table=self.widgetDict["bottomSurface"]
        )
        self.lastMaterials = (
            Utils.getTableLibrarysName(data=data.get("topSurface"), column=5)
            | Utils.getTableLibrarysName(data=data.get("bottomSurface"), column=5)
            | Utils.getTableLibrarysName(data=data.get("ySkeletal"), column=3)
        )
        self.lastStringedBars = (
            Utils.getTableLibrarysName(data=data.get("topSurface"), column=6)
            | Utils.getTableLibrarysName(data=data.get("bottomSurface"), column=6)
            | Utils.getTableLibrarysName(data=data.get("ySkeletal"), column=4)
        )

        envs.ipimas_changeStringedBar = (
            lambda library, *args, **kwargs: self.libraryChangeStringedBar(
                library, *args, **kwargs
            )
        )
        envs.ipimas_changeMaterial = (
            lambda library, *args, **kwargs: self.libraryChangeMaterial(
                library, *args, **kwargs
            )
        )

    def libraryChangeMaterial(self, library):
        if self.isVisible():
            self.materialData = library

    def libraryChangeStringedBar(self, library):
        if self.isVisible():
            self.stringedBarData = library

    def createParameterUI(self, list, layout, row=0, col=0):
        for index, item in enumerate(list):
            name = item.get("name")
            index = row + index
            label = QLabel(item["title"])
            layout.addWidget(label, index, 0 + col)
            if item["type"] == "str":
                self.widgetDict[name] = LineEditStr()
            elif item["type"] == "float":
                self.widgetDict[name] = LineEditFloat()
            elif item["type"] == "int":
                self.widgetDict[name] = LineEditInt()
            elif item["type"] == "select":
                self.widgetDict[name] = SelectBox(
                    options=item["options"], onChanged=item.get("onChanged")
                )
            layout.addWidget(self.widgetDict[name], index, 1 + col)

    def on_okBtn_clicked(self):
        dict = {}
        topSurface = self.widgetDict["topSurface"].getTableListFirstNoNull()
        if isinstance(topSurface, int):
            MBox.warning(f"上端面节点号不可为空!")
            return
        bottomSurface = self.widgetDict["bottomSurface"].getTableListFirstNoNull()
        if isinstance(bottomSurface, int):
            MBox.warning(f"下端面行节点号不可为空!")
            return
        if topSurface and len(topSurface) > 0:
            top = [None if item == "" else item for item in topSurface[0]]
        else:
            top = []

        if bottomSurface and len(bottomSurface) > 0:
            bottom = [None if item == "" else item for item in bottomSurface[0]]
        else:
            bottom = []
        dict["grid"] = Utils.filter_dict_list([top, bottom])
        dict["grid"] = Utils.filter_dict_list(dict["grid"])
        dict["type"] = "bar_3d"

        for key, widget in self.widgetDict.items():
            if not isinstance(widget, ParamsTable):
                dict[key] = widget.getValue()

        # ySkeletal = self.widgetDict['ySkeletal'].getTableData()
        # if ySkeletal and len(ySkeletal) > 0 and len(ySkeletal[0]) > 0:
        #     dict["num_r"] = ySkeletal[0][0]
        #     dict["len_r"] = ySkeletal[0][1]
        #     dict["start_angle"] = ySkeletal[0][2]
        #     dict["num_rod"] = ySkeletal[0][3]
        #     dict["material"] = ySkeletal[0][4]
        #     dict["rib"] = ySkeletal[0][5]
        #     dict["element_start"] = ySkeletal[0][6]
        #     dict["rib_start"] = ySkeletal[0][7]

        # if Config.isLocation:
        # data = Utils.filter_dict_list(data)

        filterDict = Utils.filterDictEmptyProperty(dict)
        self.cacheFile = Config.cachePath + "skeletalStructure.json"
        Utils.write_json(self.cacheFile, filterDict)
        self.close()
        if Config.useLibraryLocking:
            materialLibrary = Utils.updateLockingLibrary(
                dataList=[
                    [dict["topSurface"], 5],
                    [dict["bottomSurface"], 5],
                    [dict["ySkeletal"], 3],
                ],
                lastSelects=self.lastMaterials,
                library=self.materialData,
                file=Config.materialTable,
            )
            stringedBarLibrary = Utils.updateLockingLibrary(
                dataList=[
                    [dict["topSurface"], 6],
                    [dict["bottomSurface"], 6],
                    [dict["ySkeletal"], 4],
                ],
                lastSelects=self.lastStringedBars,
                library=self.stringedBarData,
                file=Config.stringedBarTable,
            )
            if materialLibrary:
                if hasattr(envs, "ipimas_changeLockMaterial"):
                    envs.ipimas_changeLockMaterial()
                self.materialLibraryLocking_update_signal.emit(materialLibrary)
            if stringedBarLibrary:
                if hasattr(envs, "ipimas_changeLockStringedBar"):
                    envs.ipimas_changeLockStringedBar()
                self.stringedBarLibraryLocking_update_signal.emit(stringedBarLibrary)
        self.skeletalStructure_save_signal.emit(filterDict)

    def setTableFixeHeight(self, table):
        total_height = table.rowHeight(0)
        horizontal_header_height = table.horizontalHeader().height()
        table.setFixedHeight(total_height + horizontal_header_height)

    def saveData(self, file):
        dict = {}
        for key, widget in self.widgetDict.items():
            dict[key] = widget.getTableData()
        Utils.write_json(file, dict)

    def updateUI(self, data):
        if data:
            if data.get("grid") and len(data["grid"]) > 0:
                if data["grid"][0] and len(data["grid"][0]) > 0:
                    self.widgetDict["topSurface"].fillRowData(
                        row=0, rowData=data["grid"][0]
                    )
            if data.get("grid") and len(data["grid"]) > 1:
                if data["grid"][1] and len(data["grid"][1]) > 0:
                    self.widgetDict["bottomSurface"].fillRowData(
                        row=0, rowData=data["grid"][1]
                    )

            for widget, value in data.items():
                if widget in self.widgetDict and widget not in [
                    "topSurface",
                    "bottomSurface",
                ]:
                    self.widgetDict[widget].setValue(value)


# if __name__ == "__main__":
#     app = QApplication(sys.argv)
#     window = SkeletalStructureDialog()
#     window.show()
#     sys.exit(app.exec_())
